/* AndyDroid - Android automation testing Framework.
 Copyright (C) 2011 MicroStrategy Test Automation Team

 AndyDroid is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with software. If not, contact us.
 
 @email:	robort1002@gmail.com
 */
package com.microstrategy.android.automation.utils;

import com.microstrategy.android.automation.view.ViewConstants;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.text.format.Time;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManager;

/**
 * This class represents the device, and contains methods to operate
 * device, such as press a key.
 * 
 *
 */
public final class DeviceUtils {
	private static final String LOG_TAG = "AndyDevice";
	
	private static Instrumentation inst;
	private static ActivityUtils activityUtils;
	
	private static DeviceUtils instance;
	
	private static final String LANDSCAPE = "landscape";
	private static final String PORTRAIT = "portrait";
    
	private DeviceUtils(Instrumentation inst, Activity activity) {
		DeviceUtils.inst = inst;
		DeviceUtils.activityUtils = new ActivityUtils(inst, activity);
	}
	
	public static DeviceUtils getInstance(Instrumentation inst, Activity activity) {
		if (null == instance) {
			instance = new DeviceUtils(inst, activity);
		}
		
		return instance;
	}
	
	private WindowManager getWindowManager() {
		return getCurrentActivity().getWindowManager();
	}
	
	/**
	 * 
	 * @return
	 */
	public int getScreenHeight() {
		return getWindowManager().getDefaultDisplay().getHeight();
	}
	
	/**
	 * 
	 * @return
	 */
	public int getScreenWidth() {
		return getWindowManager().getDefaultDisplay().getWidth();
	}
	
	/**
	 * Press a series of key by codes example:(KEYCODE_DPAD_LEFT, KEYCODE_DPAD_CENTER).
	 * @param keys Keycode.
	 */
	public static void pressKeys(int... keys) {
		inst.waitForIdleSync();
		for (int i = 0; i < keys.length; i++) {
			Log.i(LOG_TAG, "send KeyCode: " + String.valueOf(keys[i]));
			inst.sendCharacterSync(keys[i]);
			inst.waitForIdleSync();
		}
	}
	
	/**
	 * Perform press the Back key.
	 */
	public static void pressBack() {
		try {
			Thread.sleep(ViewConstants.ANR_TIME);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		pressKeys(KeyEvent.KEYCODE_BACK);
	}

	/**
	 * Perform press the Menu key.
	 */
	public static void pressMenu() {
		pressKeys(KeyEvent.KEYCODE_MENU);
	}

	/**
	 * Perform press the Home key.
	 */
	public static void pressHome() {
		pressKeys(KeyEvent.KEYCODE_HOME);
	}

	/**
	 * Perform press the Up key.
	 */
	public static void pressUp() {
		pressKeys(KeyEvent.KEYCODE_DPAD_UP);
	}

	/**
	 * Perform press the Down key.
	 */
	public static void pressDown() {
		pressKeys(KeyEvent.KEYCODE_DPAD_DOWN);
	}

	/**
	 * Perform press the Left key.
	 */
	public static void pressLeft() {
		pressKeys(KeyEvent.KEYCODE_DPAD_LEFT);
	}

	/**
	 * Perform press the Right key.
	 */
	public static void pressRight() {
		pressKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
	}

	/**
	 * Perform press the Enter key.
	 */
	public static void pressEnter() {
		pressKeys(KeyEvent.KEYCODE_ENTER);
	}
	
	static Activity getCurrentActivity() {
		return activityUtils.getCurrentActivity();
	}
	
	/**
	 * Sets the Orientation (Landscape/Portrait) for the current activity.
	 * @param orientation
	 *            An orientation constant such as
	 *            {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}
	 *            or
	 *            {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_PORTRAIT}
	 *            .
	 */
	public void setScreenOrientation(int orientation) {
		activityUtils.setActivityOrientation(orientation);
		inst.waitForIdleSync();
	}
	
	/**
	 * Get the Orientation (Landscape/Portrait) for the current activity.
	 * @return landscape or portrait.
	 */
	public String getScreenOrientation() {
		inst.waitForIdleSync();
		int orientation = getCurrentActivity().getRequestedOrientation();
		return (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE == orientation) ? LANDSCAPE
				: PORTRAIT; 
	}
	
	/**
	 * Waits for the given {@link Activity}.
	 * 
	 * @param name
	 *            the name of the {@code Activity} to wait for e.g.
	 *            {@code "MyActivity"}
	 * @param timeout
	 *            the amount of time in milliseconds to wait
	 * @return {@code true} if {@code Activity} appears before the timeout and
	 *         {@code false} if it does not
	 * 
	 */
	public boolean waitForActivity(String name, int timeout) {
		return activityUtils.waitForActivity(name, timeout);
	}
	
	/**
	 * Returns to the given {@link Activity}.
	 * @param name
	 *            the name of the {@code Activity} to return to, e.g.
	 *            {@code "MyActivity"}
	 * 
	 */
	public void goBackToActivity(String name){
		activityUtils.goBackToActivity(name);
	}
}
